package tools;

import java.util.ArrayList;

import data.set.OfflineSet;
import data.set.OfflineSetIterator;
import data.set.implementation.OfflineSet_Memory;

public class OfflineSetOperator {
	public static <T> Pair<OfflineSet<T>, OfflineSet<T>> separate(OfflineSet<T> set, int num){
		OfflineSet_Memory<T> s = new OfflineSet_Memory<T>(), 
		o = new OfflineSet_Memory<T>();
		int i=0, demi=(int) (set.size()/2);
		
		OfflineSetIterator<T> iter = set.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			int id = iter.getCurrentId();
			T instance = iter.getCurrentObject();
			if(i%demi<num)
				s.add(id, instance);
			else
				o.add(id, instance);
			i++;
		}
		
		return new Pair<OfflineSet<T>, OfflineSet<T>>(s, o);
	}
	
	public static <T> Pair<OfflineSet<T>, OfflineSet<T>> separate(OfflineSet<T> set, double rate){
		OfflineSet_Memory<T> s = new OfflineSet_Memory<T>(), 
		o = new OfflineSet_Memory<T>();
		int sNum=(int) (set.size()*rate/2), i=0, demi=(int) (set.size()/2);
		
		OfflineSetIterator<T> iter = set.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			int id = iter.getCurrentId();
			T instance = iter.getCurrentObject();
			if(i%demi<sNum)
				s.add(id, instance);
			else
				o.add(id, instance);
			i++;
		}
		
		return new Pair<OfflineSet<T>, OfflineSet<T>>(s, o);
	}
	
	public static <T> Pair<OfflineSet<T>, OfflineSet<T>> sample(OfflineSet<T> set, double rate){
		OfflineSet_Memory<T> s = new OfflineSet_Memory<T>(), 
		o = new OfflineSet_Memory<T>();
		
		OfflineSetIterator<T> iter = set.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			int id = iter.getCurrentId();
			T instance = iter.getCurrentObject();
			if(Math.random()<rate)
				s.add(id, instance);
			else
				o.add(id, instance);
		}
		
		return new Pair<OfflineSet<T>, OfflineSet<T>>(s, o);
	}
	
	public static <T> ArrayList<OfflineSet_Memory<T>> sample(OfflineSet<T> set, int nb){
		ArrayList<OfflineSet_Memory<T>> s = new ArrayList<OfflineSet_Memory<T>>();
		for(int i=0; i<nb; i++){
			s.add(new OfflineSet_Memory<T>());
		}
		double k = 1.0/nb;
		
		OfflineSetIterator<T> iter = set.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			int id = iter.getCurrentId();
			T instance = iter.getCurrentObject();
			s.get((int) Math.floor(Math.random()/k)).add(id, instance);
		}
		
		return s;
	}
	
	public static <T> OfflineSet<T> combin(OfflineSet<T> set1, OfflineSet<T> set2){
		OfflineSet_Memory<T> r = new OfflineSet_Memory<T>();
		OfflineSetIterator<T> iter = set1.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			r.add(iter.getCurrentId(), iter.getCurrentObject());
		}
		iter = set2.inputsetiterator();
		while(iter.hasNext()){
			iter.next();
			r.add(iter.getCurrentId(), iter.getCurrentObject());
		}
		
		return r;
	}
}
